package com.ego.ware.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ego.common.constant.SystemConstant;
import com.ego.common.constant.WareConstant;
import com.ego.common.exception.GlobalException;
import com.ego.common.util.PageUtil;
import com.ego.common.vo.PageVo;
import com.ego.ware.po.PurchaseDetail;
import com.ego.ware.service.PurchaseDetailService;
import com.ego.ware.service.WareSkuService;
import com.ego.ware.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ego.ware.dao.PurchaseDao;
import com.ego.ware.po.Purchase;
import com.ego.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author KamTang
 * @program: ego
 * @description 采购信息对应实现类
 * @date 2022-11-13 13:30:29
 */
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, Purchase> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private WareSkuService wareSkuService;

    @Override
    public PageVo<Purchase> search(PurchaseSearchVo searchVo) {
        LambdaQueryWrapper<Purchase> query = Wrappers.<Purchase>lambdaQuery()
                .eq(searchVo.getStatus() != null, Purchase::getStatus, searchVo.getStatus());
        if (StringUtils.isNotEmpty(searchVo.getKeyword())) {
            query.like(Purchase::getAssigneeName, searchVo.getKeyword())
                    .or().like(Purchase::getPhone, searchVo.getKeyword());
        }
        Page<Purchase> page = this.baseMapper.selectPage(Page.of(searchVo.getPageNum(), searchVo.getPageSize()), query);
        return PageUtil.toPage(page);
    }

    @Override
    public List<Purchase> unreceived() {
        LambdaQueryWrapper<Purchase> query = Wrappers.<Purchase>lambdaQuery()
                .eq(Purchase::getStatus, 0)
                .or().eq(Purchase::getStatus, 1);
        return this.baseMapper.selectList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean receive(List<Long> ids) {
        // 确认当前采购单是新建或者已分配状态
        List<Purchase> purchases = this.baseMapper.selectList(new QueryWrapper<Purchase>().in("id", ids))
                .stream().filter(Purchase::available)
                .peek(Purchase::receiving).collect(Collectors.toList());

        // 改变采购单的状态
        this.updateBatchById(purchases);

        // 改变采购项的状态
        purchases.forEach(purchase -> {
            List<PurchaseDetail> purchaseDetails = purchaseDetailService
                    .list(new QueryWrapper<PurchaseDetail>().eq("purchase_id", purchase.getId()));
            List<PurchaseDetail> purchaseDetailPos = purchaseDetails.stream().map(purchaseDetail -> {
                PurchaseDetail purchaseDetailPo = new PurchaseDetail();
                purchaseDetailPo.purchasing(purchaseDetail);
                return purchaseDetailPo;
            }).collect(Collectors.toList());
            purchaseDetailService.updateBatchById(purchaseDetailPos);
        });
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finished(PurchaseFinishedVo finished) {
        // 改变采购项的状态
        boolean status = true;
        List<PurchaseDetail> purchaseDetails = purchaseDetailService
                .list(new QueryWrapper<PurchaseDetail>().eq("purchase_id", finished.getId()));
        for (PurchaseDetail item : purchaseDetails
        ) {
            if (finished.hasError()) {
                status = false;
            } else {
                item.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISHED.getCode());
                // 将成功采购的进行入库
                wareSkuService.stock(item);
            }
        }
        purchaseDetailService.updateBatchById(purchaseDetails);
        // 改变采购单状态
        Purchase purchaseEntity = new Purchase();
        purchaseEntity.finished(finished.getId(), status);
        this.updateById(purchaseEntity);
    }

    @Override
    public List<PurchaseVo> list(Long adminId) {
        if (adminId != null) {
            QueryWrapper<Purchase> query = new QueryWrapper<Purchase>()
                    .in("status", WareConstant.PurchaseStatusEnum.ASSIGNED.getCode(),
                            WareConstant.PurchaseStatusEnum.RECEIVED.getCode(),
                            WareConstant.PurchaseStatusEnum.FINISHED.getCode())
                    .eq("assignee_id", adminId);
            List<Purchase> purchases = this.baseMapper.selectList(query);
            // 收集采购单id
            List<Long> purchaseIds = purchases.stream().map(Purchase::getId).collect(Collectors.toList());
            // 从采购需求中获取其他信息（商品名称、库存名称、采购金额）
            List<PurchaseDetail> purchaseDetails = purchaseDetailService
                    .list(new QueryWrapper<PurchaseDetail>().in("purchase_id", purchaseIds)
                            .in("status", WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode(),
                                    WareConstant.PurchaseDetailStatusEnum.BUYING.getCode(),
                                    WareConstant.PurchaseDetailStatusEnum.FINISHED.getCode()));
            if (CollectionUtil.isNotEmpty(purchaseDetails)) {
                // toVo
                List<PurchaseVo> purchaseVos = purchases.stream().map(Purchase::toVo).collect(Collectors.toList());
                return purchaseVos.stream().peek(purchaseVo -> {
                    List<PurchaseDetail> currentPurchaseDetail = purchaseDetails.stream().map(detail -> {
                        if (detail.getPurchaseId().equals(purchaseVo.getId())) {
                            return detail;
                        }
                        return null;
                    }).filter(Objects::nonNull).collect(Collectors.toList());
                    List<String> skuNames = new ArrayList<>();
                    BigDecimal total = BigDecimal.ZERO;
                    for (PurchaseDetail purchaseDetail : currentPurchaseDetail) {
                        total = total.add(purchaseDetail.getSkuPrice().multiply(new BigDecimal(purchaseDetail.getSkuNum())));
                        skuNames.add(purchaseDetail.getWareName() + "需购买【" + purchaseDetail.getSkuName() + "】× " + purchaseDetail.getSkuNum().toString() + "件。");
                    }
                    purchaseVo.setAmount(total);
                    purchaseVo.setSkuNames(skuNames);
                }).collect(Collectors.toList());
            } else {
                throw new GlobalException(SystemConstant.Status.WARE_EXCEPTION.getMsg(),
                        SystemConstant.Status.WARE_EXCEPTION.getCode());
            }
        }
        return new ArrayList<>();
    }
}
